/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package engine.linkList;

/**
 *
 * @author hjp
 */
import engine.decoder.ID3Decoder;
import engine.player.MusicPlayer;
import java.io.*;

public class Init_Save {

    private Init_Save(){

    }

    /**
     * 播放器启动的时候调用
     */
    public static void init(){
        File serFile_CreateMusicLists = new File("CreateMusicLists.ser");
        File serFile_CollectedMusicLists = new File("CollectedMusicLists.ser");
        File serFile_LocalToScanFolderList = new File("LocalToScanFolderList.ser");
        File serFile_PlayScheduleManager = new File("PlayScheduleManager.ser");
        File serFile_MusicPlayer = new File("MusicPlayer.ser");
        ObjectInputStream in;
        Node<MusicListNode> listNode;
        Integer integer;
        if (serFile_CreateMusicLists.exists() && serFile_CollectedMusicLists.exists() && serFile_LocalToScanFolderList.exists()){
            /*
             *初始化LinkedListManager
             */
            try {
                /*
                1.反序列化createMusicLists
                 */
                in = new ObjectInputStream(new FileInputStream(serFile_CreateMusicLists));
                try{
                    LinkedListManager.manager.createMusicLists = new MusicLists();
                    integer = (Integer)in.readObject();
                    if (integer != null) {
                            LinkedListManager.manager.createMusicLists.sum = integer;
                            listNode = (Node<MusicListNode>)in.readObject();
                            LinkedListManager.manager.createMusicLists.head = listNode;
                           Node<MusicListNode> p = LinkedListManager.manager.createMusicLists.head;
                           --integer;
                           while(integer != 0){
                              p = p .next;
                             --integer;
                            }
                        LinkedListManager.manager.createMusicLists.tail = p;
                    }
                }
                catch (IOException | ClassNotFoundException e){
                    e.printStackTrace();
                    LinkedListManager.manager.createMusicLists = new MusicLists();
                }
                in.close();
                /*
                2.反序列化collectedMusicLists
                 */
                //当前尚不支持收藏某个歌单
                LinkedListManager.manager.collectedMusicLists = new MusicLists();
                /*
                3.反序列化localToScanFolderList
                 */
                in = new ObjectInputStream(new FileInputStream(serFile_LocalToScanFolderList));
                try{
                    LinkedListManager.manager.localToScanFolderList = new LocalToScanFolderList();
                    integer = (Integer)in.readObject();
                    if (integer != null){
                       LinkedListManager.manager.localToScanFolderList.sum = integer;
                       Node<LocalToScanFolderNode> folderNode = (Node<LocalToScanFolderNode>)in.readObject();
                       LinkedListManager.manager.localToScanFolderList.head = folderNode;
                       Node<LocalToScanFolderNode> p = LinkedListManager.manager.localToScanFolderList.head;
                       --integer;
                       while(integer != 0){
                             p = p .next;
                             --integer;
                       }
                       LinkedListManager.manager.localToScanFolderList.tail = p;
                    }
                }catch (IOException | ClassNotFoundException e){
                    e.printStackTrace();
                    LinkedListManager.manager.localToScanFolderList = new LocalToScanFolderList();
                }
                in.close();
                /*
                4.初始化本地音乐链表localListNode
                 */
                LinkedListManager.manager.localListNode = LinkedListManager.manager.scanAndCreateLocalListNode();
                LinkedListManager.manager.localListNode.info.listName = "本地歌单";
                /*
                5.初始化播放器显示的歌单集合以及歌单
                方案：初始化的是，默认显示的歌单为本地歌单，歌单集合自然就为空了
                 */
                LinkedListManager.manager.currentVisitMusicLists = null; 
                LinkedListManager.manager.currentVisitMusicList = LinkedListManager.manager.localListNode;//当前显示的歌单可能为空
                /*
                6.初始化downloadedListNode和downlaodingListNode
                 */
                LinkedListManager.manager.downloadedListNode = new Node<>(new MusicListNode());
                LinkedListManager.manager.downlaodingListNode = new Node<>(new MusicListNode());
                /*
                7.初始化爬虫返回的歌单crawlerMusicLists
                 */
                //todo 调用爬虫模块以初始化crawlerMusicLists
                LinkedListManager.manager.crawlerMusicLists = null;
            } catch (IOException e) {
                e.printStackTrace();
                //当发生了任何异常的时候，执行默认初始化
                defaultInit_LinkedListManager();
            }
            /*
            2.初始化PlayScheduleManager
             */
            try {
                in = new ObjectInputStream(new FileInputStream(serFile_PlayScheduleManager));
                /*
                1.初始化currentPlayMusicLists
                 */
                try {
                    integer = (Integer)in.readObject();
                    if (integer == null) {
                        PlayScheduleManager.manager.currentPlayMusicLists = null;
                    } else if (integer == 1) {
                        PlayScheduleManager.manager.currentPlayMusicLists = LinkedListManager.manager.createMusicLists;
                    } else if (integer == 2){
                        PlayScheduleManager.manager.currentPlayMusicLists = LinkedListManager.manager.collectedMusicLists;
                    }
                }catch (IOException | ClassNotFoundException e){
                    e.printStackTrace();
                    PlayScheduleManager.manager.currentPlayMusicLists = null;
                }
                /*
                2.初始化currentPlayMusicList
                 */
                try {
                    integer = (Integer)in.readObject();
                    if (integer == null) {
                        PlayScheduleManager.manager.currentPlayMusicList = null;
                    }
                    else if (integer == 0){
                        //此时，代表当前播放歌单为本地歌单
                        PlayScheduleManager.manager.currentPlayMusicList = LinkedListManager.manager.localListNode;
                    }
                    else {
                        Node<MusicListNode> p = PlayScheduleManager.manager.currentPlayMusicLists.head;
                        --integer;
                        while (integer != 0){
                            p = p.next;
                            --integer;
                        }
                        PlayScheduleManager.manager.currentPlayMusicList = p;
                    }
                }catch (IOException | ClassNotFoundException e){
                    e.printStackTrace();
                    PlayScheduleManager.manager.currentPlayMusicList = null;
                }
                /*
                3.反序列化currentMode
                 */
                try {
                    PlayMode mode = (PlayMode)in.readObject();
                    if (mode == null){
                        //此时设置默认播放模式
                        PlayScheduleManager.manager.currentMode = PlayMode.SEQUENCE;
                        //test
                        System.out.println("null");
                    }
                    else {
                        PlayScheduleManager.manager.currentMode = mode;
                        //test
                        System.out.println(PlayScheduleManager.manager.currentMode);
                    }
                }catch (IOException | ClassNotFoundException e){
                    e.printStackTrace();
                    //此时设置默认播放模式
                    PlayScheduleManager.manager.currentMode = PlayMode.SEQUENCE;
                }
                 /*
                4.初始化2个副本链表
                 */
                Node<MusicListNode> p = PlayScheduleManager.manager.currentPlayMusicList;//p可能为空
                //p可能为空，所以以下两个副本链表也可能指向null
                PlayScheduleManager.manager.musicListCopy = PlayScheduleManager.manager.createSequenceMusicList(p);
                PlayScheduleManager.manager.musicListCopyRandom = PlayScheduleManager.manager.createRandomMusicList(p);
                /*
                5.反序列化pCurrentPlayMusicNodeCopy
                 */
                MusicNode node = null;
                try{
                    node = (MusicNode)in.readObject();
                }catch (IOException | ClassNotFoundException e){
                    e.printStackTrace();
                }
                in.close();
                /*
                6.初始化pCurrentPlayMusicListCopy
                 */
                //由于两个副本链表可能指向null，故pCurrentPlayMusicListCopy可能为空
                switch (PlayScheduleManager.manager.currentMode){
                    case SEQUENCE:
                    case SINGLE_CYCLE:{
                        PlayScheduleManager.manager.pCurrentPlayMusicListCopy = PlayScheduleManager.manager.musicListCopy;
                        break;
                    }
                    case RANDOM:{
                        PlayScheduleManager.manager.pCurrentPlayMusicListCopy = PlayScheduleManager.manager.musicListCopyRandom;
                        break;
                    }
                }
                /*
                7.初始化pCurrentPlayMusicNodeCopy
                 */
                //pCurrentPlayMusicNodeCopy可能会被指向null
                PlayScheduleManager.manager.pCurrentPlayMusicNodeCopy = PlayScheduleManager.manager.findSelectedMusicNode(new Node<>(node));
                //当findSelectedMusicNode返回空，（即上次序列化保存的歌曲是从别的链表中插播的），且当前播放歌单不为空，则pCurrentPlayMusicNodeCopy可以不为空
                if (PlayScheduleManager.manager.pCurrentPlayMusicNodeCopy == null && PlayScheduleManager.manager.currentPlayMusicList != null){
                    PlayScheduleManager.manager.pCurrentPlayMusicNodeCopy = PlayScheduleManager.manager.pCurrentPlayMusicListCopy.info.head;
                }
            }catch (IOException e){
                e.printStackTrace();
                defaultInit_PlayScheduleManager();
            }
            /*
            * 3.初始化MusicPlayer
            */
            try{
                in = new ObjectInputStream(new FileInputStream(serFile_MusicPlayer));
                //1.初始化当前播放到的时间
                Integer time = (Integer)in.readObject();
                if (time != null && PlayScheduleManager.manager.pCurrentPlayMusicNodeCopy != null) {
                    //MusicPlayer.currentPlayTime = time;
                    MusicPlayer.currentPlayTime = 0;
                    //2.将buffer正确置位
                    MusicPlayer.musicPlayer.buffer = new BufferedInputStream(new FileInputStream(PlayScheduleManager.manager.pCurrentPlayMusicNodeCopy.info.filePath));
                    //double percent = (MusicPlayer.musicPlayer.currentPlayTime * 1.0 / 1000) / (PlayScheduleManager.manager.pCurrentPlayMusicNodeCopy.info.time * 1.0);
                    //MusicPlayer.musicPlayer.buffer.skip((long)(ID3Decoder.getv2tagSize(PlayScheduleManager.manager.pCurrentPlayMusicNodeCopy.info.filePath) + percent * PlayScheduleManager.manager.pCurrentPlayMusicNodeCopy.info.size));
                }
                else{
                    MusicPlayer.musicPlayer.currentPlayTime = 0;
                    //2.将buffer正确置位
                    MusicPlayer.musicPlayer.buffer = null;
                }
                in.close();
            }catch(IOException | ClassNotFoundException e){
                 MusicPlayer.musicPlayer.currentPlayTime = 0;
                 MusicPlayer.musicPlayer.buffer = null;
                 e.printStackTrace();
            }
        }
        //当LinkedListManager序列化文件不存在的时候,两者都执行默认初始化，即统统置空
        else {
            defaultInit_LinkedListManager();
            defaultInit_PlayScheduleManager();
            defaultInit_MusicPlayer();
        }
    }

    /**
     * 播放器退出的时候调用
     */
    public static void save(){
        File serFile_CreateMusicLists = new File("CreateMusicLists.ser");
        File serFile_CollectedMusicLists = new File("CollectedMusicLists.ser");
        File serFile_LocalToScanFolderList = new File("LocalToScanFolderList.ser");
        File serFile_PlayScheduleManager = new File("PlayScheduleManager.ser");
        File serFile_MusicPlayer = new File("MusicPlayer.ser");
        ObjectOutputStream out;
        /*
        *保存LinkedListManager
        */
        //1.序列化createMusicLists
        try{
            out = new ObjectOutputStream(new FileOutputStream(serFile_CreateMusicLists));
           if (LinkedListManager.manager.createMusicLists.sum == 0){
               out.writeObject(null);
           }
           else {
               //先序列化歌单集合中歌单总数，在序列化每一首歌单
               out.writeObject(LinkedListManager.manager.createMusicLists.sum);
               Node<MusicListNode> p = LinkedListManager.manager.createMusicLists.head;
               while(p != null){
                   out.writeObject(p);//序列化创建的歌单
                   p = p.next;
               }
           }
           out.close();
        }catch(IOException e){
            e.printStackTrace();
        }
        //2.序列化collectedMusicLists
        try{
            out = new ObjectOutputStream(new FileOutputStream(serFile_CollectedMusicLists));
            //暂不支持收藏某个歌单
            out.writeObject(null);
        }catch(IOException e){
            e.printStackTrace();
        }
        //3.序列化localToScanFolderList
        try{
            out = new ObjectOutputStream(new FileOutputStream(serFile_LocalToScanFolderList));
             if (LinkedListManager.manager.localToScanFolderList.sum == 0){
               out.writeObject(null);
           }
           else {
               //先序列化但扫描文件夹链表中文件夹结点总数，在序列化每一个文件夹结点
               out.writeObject(LinkedListManager.manager.localToScanFolderList.sum);
               Node<LocalToScanFolderNode> p = LinkedListManager.manager.localToScanFolderList.head;
               while(p != null){
                   out.writeObject(p);
                   p = p.next;
               }
           }
        }catch(IOException e){
            e.printStackTrace();
        }
        /*
        *保存PlayScheduleManager
        */
        try {
            out = new ObjectOutputStream(new FileOutputStream(serFile_PlayScheduleManager));
            /*
           1.序列化currentPlayMusicLists
            */
           //找到当前播放的歌单集合是第几个
           //当且仅当播放器曾经播放过某首歌曲且该歌曲所在的歌单没有被删除，currentPlayMusicLists才非空
           //则，该命题的逆命题为，当播放器从未播放任何一首歌曲的时候，
           //或者播放的歌曲所在的歌单被删除了，currentPlayMusicLists才为空。
           //而这上述着两种情况，currentPlayMusicLists都应当在序列化存储的时候写入空。
           if (PlayScheduleManager.manager.currentPlayMusicLists == null){
               out.writeObject(null);
           }
           else if (PlayScheduleManager.manager.currentPlayMusicLists == LinkedListManager.manager.createMusicLists){
               out.writeObject(1);
           }
           else if (PlayScheduleManager.manager.currentPlayMusicLists == LinkedListManager.manager.collectedMusicLists){
               out.writeObject(2);
           }
           /*
           2.序列化currentPlayMusicList
            */
           //当且仅当播放器曾经播放过某首歌曲且该歌曲所在的歌单没有被删除，currentPlayMusicList才非空
           //则，该命题的逆命题为，当播放器从未播放任何一首歌曲的时候，
           //或者播放的歌曲所在的歌单被删除了，currentPlayMusicList才为空。
           //而这上述着两种情况，currentPlayMusicList都应当在序列化存储的时候写入空。
           if (PlayScheduleManager.manager.currentPlayMusicList == null){
               //原始版本下的将null写入序列化文件的条件：
               //currentPlayMusicLists == null || (currentPlayMusicList == null || currentPlayMusicList.info == null)
               out.writeObject(null);
           }
           else {
               //否则找到currentPlayMusicList是所在歌单集合中的第几个歌单
               //如果此时播放的是本地歌单,则将0序列化存储。代表此时当前播放的歌单为本地歌单
               if (PlayScheduleManager.manager.currentPlayMusicList == LinkedListManager.manager.localListNode) {
                   out.writeObject(0);
               }
               else{
                   if(PlayScheduleManager.manager.currentPlayMusicList != null){
                        Node<MusicListNode> p = PlayScheduleManager.manager.currentPlayMusicLists.head;
                        int index = 1;
                        while (p != null){
                            if (p == PlayScheduleManager.manager.currentPlayMusicList){
                                break;
                            }
                            ++index;
                            p = p.next;
                        }
                        out.writeObject(index);
                   }
                   else{
                       out.writeObject(0);
                   }
               }
           }
           /*
           3.保存当前播放模式currentMode
            */
           if (PlayScheduleManager.manager.currentPlayMusicList == null){
               out.writeObject(null);
           }
           else {
               out.writeObject(PlayScheduleManager.manager.currentMode);
           }
           /*
           4.保存当前播放歌曲结点的值pCurrentPlayMusicNodeCopy
            */
           if (PlayScheduleManager.manager.currentPlayMusicList == null){
               //原始版本的条件：
               //pCurrentPlayMusicNodeCopy == null || currentPlayMusicList == null || currentPlayMusicList.info == null
               out.writeObject(null);
           }
           else {
               out.writeObject(PlayScheduleManager.manager.pCurrentPlayMusicNodeCopy.info);
           }
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //序列化MusicPlayer
        try {
            out = new ObjectOutputStream(new FileOutputStream(serFile_MusicPlayer));
             if (PlayScheduleManager.getInstance().currentPlayMusicList != null) {
                out.writeObject(MusicPlayer.currentPlayTime);
            }
            else{
                out.writeObject(null);
            }
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 对LinkedListManager执行默认初始化
     */
    private static void defaultInit_LinkedListManager(){
        LinkedListManager.manager.createMusicLists = new MusicLists();
        LinkedListManager.manager.collectedMusicLists = new MusicLists();
        LinkedListManager.manager.localToScanFolderList = new LocalToScanFolderList();
        LinkedListManager.manager.localListNode = new Node<>(new MusicListNode());
        LinkedListManager.manager.localListNode.info.listName = "本地歌单";
        //初始化的时候，显示的歌单为本地歌单
        LinkedListManager.manager.currentVisitMusicLists = null;
        LinkedListManager.manager.currentVisitMusicList = LinkedListManager.manager.localListNode;
        LinkedListManager.manager.downloadedListNode = new Node<>(new MusicListNode());
        LinkedListManager.manager.downlaodingListNode = new Node<>(new MusicListNode());
        //todo 调用爬虫模块以初始化crawlerMusicLists
        LinkedListManager.manager.crawlerMusicLists = null;
    }

    /**
     * 对PlayScheduleManager执行默认初始化
     */
    private static void defaultInit_PlayScheduleManager(){
        PlayScheduleManager.manager.currentPlayMusicLists = null;
        PlayScheduleManager.manager.currentPlayMusicList = null;
        PlayScheduleManager.manager.currentMode = PlayMode.SEQUENCE;
        PlayScheduleManager.manager.pCurrentPlayMusicNodeCopy = null;
        PlayScheduleManager.manager.pCurrentPlayMusicListCopy = null;
        PlayScheduleManager.manager.musicListCopy = null;
        PlayScheduleManager.manager.musicListCopyRandom = null;
    }
    
    private static void defaultInit_MusicPlayer(){
        MusicPlayer.currentPlayTime = 0;
        MusicPlayer.musicPlayer.buffer = null;
    }
}

